package lib.self.ex.activity;

import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnPreDrawListener;

import androidx.annotation.AnimRes;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;

import com.gyf.immersionbar.ImmersionBar;

import lib.self.LogMgr;
import lib.self.R;
import lib.self.ex.decor.NewDecorView;
import lib.self.ex.decor.TitleBarEx;
import lib.self.ex.dialog.DialogEx;
import lib.self.ex.instance.LoadingDialog;
import lib.self.ex.interfaces.IFitParams;
import lib.self.ex.interfaces.IInitialize;
import lib.self.ex.interfaces.INetwork;
import lib.self.ex.interfaces.IOption;
import lib.self.ex.interfaces.OnRetryClickListener;
import lib.self.fresco.NetworkImageView;
import lib.self.network.NetworkExecutor;
import lib.self.network.bean.NetworkListener;
import lib.self.network.bean.NetworkRequest;
import lib.self.network.bean.NetworkResponse;
import lib.self.network.error.NetError;
import lib.self.params.TitleBarState;
import lib.self.params.TitleBarState.ITitleBarState;
import lib.self.util.autoFit.FitDpUtil;
import lib.self.util.autoFit.FitViewParamsUtil;
import lib.self.util.view.ViewUtil;
import lib.self.utils.ActAnimUtil;
import lib.self.utils.DeviceUtil;
import lib.self.utils.ToastUtil;
import lib.self.utils.UiUtil;

/**
 * description: Activity基类
 * author: Steven Xiao
 * date: 2017/5/22
 */
public abstract class ActivityEx extends AppCompatActivity implements IFitParams, INetwork, IInitialize, OnClickListener, IOption, OnRetryClickListener {
    protected final String TAG = getClass().getSimpleName();
    public View mTopView;
    protected ImmersionBar mImmersionBar;
    private NetworkExecutor mNetworkExecutor;
    private NewDecorView mDecorView;
    private boolean mInitComplete;
    private DialogEx mLoadingDialog;

    @Override
    public int getContentHeaderViewId() {
        return 0;
    }

    public int getParentContentViewId() {
        return R.layout.activity_ex_fit;
    }

    public void addContentView(@LayoutRes int layoutResID) {
        mTopView = findViewById(R.id.top_view);
        mDecorView = findViewById(R.id.activity_view_decor);
        mDecorView.setTitleBarState(getTitleBarState());
        mDecorView.setContentView(layoutResID, getContentHeaderViewId());
        autoFitAll(mDecorView);
        init();

        if (useFullScreen() && DeviceUtil.getSDKVersion() > VERSION_CODES.JELLY_BEAN_MR2) {
            UiUtil.setStatusBar(mTopView, getStatusBarBackgroundColor());
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getParentContentViewId());
        addContentView(getContentViewId());

        setOnRetryClickListener(this);

        startInAnim();

        setStatusBar();
    }

    protected void setStatusBar() {
        mImmersionBar = ImmersionBar.with(this);
        mImmersionBar.statusBarDarkFont(true, 0.2f);
        mImmersionBar.init();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        NetworkImageView.clearMemoryCache();
        System.gc();
    }

    @Override
    protected void onDestroy() {
        try {
            super.onDestroy();
        } catch (Exception e) {
            LogMgr.e(TAG, e.getMessage());
        }

        FitViewParamsUtil.clearFitSet();

        if (mNetworkExecutor != null) {
            mNetworkExecutor.destroy();
            mNetworkExecutor = null;
        }
    }

    public void setOnClickListener(@IdRes int id) {
        View view = findViewById(id);
        if (view != null) {
            view.setOnClickListener(this);
        }
    }

    protected void setOnClickListener(@IdRes int... ids) {
        for (int id : ids) {
            setOnClickListener(id);
        }
    }

    private void init() {
        initData();
        initTitleBar();
        findViews();
        setViewsValue();

        mInitComplete = true;
    }

    /**
     * 使用全屏模式--沉浸模式
     */
    protected boolean useFullScreen() {
        return false;
    }

    @ColorInt
    protected int getStatusBarBackgroundColor() {
        return 0;
    }


    /**
     * 获取titleBar的状态
     *
     * @return 0表示使用整体设置
     */
    protected @ITitleBarState
    int getTitleBarState() {
        return TitleBarState.KLinear;
    }

    /**
     * 数据请求相关
     */
    @Override
    public void exeNetworkRequest(int tag, NetworkRequest request) {
        exeNetworkRequest(tag, request, this);
    }

    @Override
    public void exeNetworkRequest(int tag, NetworkRequest request, NetworkListener listener) {
        if (isFinishing()) {
            return;
        }
        if (mNetworkExecutor == null) {
            mNetworkExecutor = new NetworkExecutor(getClass().getName(), this);
        }
        mNetworkExecutor.execute(tag, request, listener);
    }

    @Override
    public void cancelAllNetworkRequest() {
        if (mNetworkExecutor != null) {
            mNetworkExecutor.cancelAll();
        }
    }

    @Override
    public void cancelNetworkRequest(int tag) {
        if (mNetworkExecutor != null) {
            mNetworkExecutor.cancel(tag);
        }
    }

    @Override
    public Object onNetworkResponse(int id, NetworkResponse nr) {
        return null;
    }

    @Override
    public void onNetworkSuccess(int id, Object result) {
    }

    @Override
    public void onNetworkError(int id, NetError error) {
        LogMgr.e(TAG, "onNetworkError(): " + "what = [" + id + "], error = [" + error + "]");
    }

    @Override
    public void onNetworkProgress(int id, float progress, long totalSize) {
    }

    @Override
    public void onClick(View v) {
    }

    @Override
    public void showView(View view) {
        ViewUtil.showView(view);
    }

    @Override
    public void hideView(View view) {
        ViewUtil.hideView(view);
    }

    @Override
    public void goneView(View view) {
        ViewUtil.goneView(view);
    }

    @Override
    public void startActivity(Class<? extends Activity> cls) {
        startActivity(new Intent(this, cls));
    }

    @Override
    public void startActivityForResult(Class<? extends Activity> cls, int requestCode) {
        Intent intent = new Intent(this, cls);
        startActivityForResult(intent, requestCode);
    }

    public void startService(Class<? extends Service> cls) {
        Intent intent = new Intent(this, cls);
        if (VERSION.SDK_INT >= VERSION_CODES.O) {
            startForegroundService(intent);
        } else {
            startService(intent);
        }
    }

    public void showToast(String text) {
        ToastUtil.showToast(this, text);
    }

    public void showToast(@StringRes int resId) {
        ToastUtil.showToast(this, resId);
    }

    /**
     * 适配相关
     */

    @Override
    public void autoFitAll(View view) {
        FitViewParamsUtil.autoFitAll(view);
    }

    @Override
    public int dpToPx(float dp) {
        return FitDpUtil.dpToPx(dp, this);
    }

    @Override
    public boolean onRetryClick() {
        return false;
    }

    protected void setOnRetryClickListener(OnRetryClickListener listener) {
        mDecorView.setOnRetryClickListener(listener);
    }

    protected boolean initComplete() {
        return mInitComplete;
    }

    @Override
    public void finish() {
        super.finish();
        startOutAnim();
    }

    /**
     * 进入动画
     */
    protected void startInAnim() {
        startActSwitch(R.anim.left_in, R.anim.left_out);
    }

    /**
     * 退出动画
     */
    protected void startOutAnim() {
        startActSwitch(R.anim.right_in, R.anim.right_out);
    }

    /**
     * 切换动画
     */
    protected void startActSwitch(@AnimRes int enterAnim, @AnimRes int exitAnim) {
        ActAnimUtil.startActAnim(this, enterAnim, exitAnim);
    }

    /**
     * @return 获取业面状态
     */
    protected int getViewState() {
        return mDecorView.getViewState();
    }

    public void setViewState(int state) {
        mDecorView.setViewState(state);
    }

    @Override
    public void onBackPressed() {
        if (needHandleKeyBackEvent()) {
            handleKeyBackEvent();
        } else {
            super.onBackPressed();
        }
    }

    /**
     * 是否需要捕捉返回键事件
     *
     * @return 不需要
     */
    protected boolean needHandleKeyBackEvent() {
        return false;
    }

    protected void handleKeyBackEvent() {
    }

    /**
     * 初始化loading dialog
     */
    protected DialogEx initLoadingDialog() {
        DialogEx dialog = new LoadingDialog(this);
        dialog.setOnCancelListener(listener -> {
            cancelAllNetworkRequest();
            dismissLoadingDialog();
        });
        return dialog;
    }

    protected void showLoadingDialog() {
        if (mLoadingDialog == null) {
            mLoadingDialog = initLoadingDialog();
        }
        if (!isFinishing()) {
            mLoadingDialog.show();
        }
    }

    protected void dismissLoadingDialog() {
        if (mLoadingDialog == null) {
            mLoadingDialog = initLoadingDialog();
        }
        if (!isFinishing()) {
            mLoadingDialog.dismiss();
        }
    }

    protected void setBackgroundResource(@DrawableRes int resId) {
        mDecorView.setBackgroundResource(resId);
    }

    protected ImmersionBar getImmersionBar() {
        return mImmersionBar;
    }

    protected void setBackgroundColor(@ColorInt int color) {
        mDecorView.setBackgroundColor(color);
    }

    protected NewDecorView getDecorView() {
        return mDecorView;
    }

    protected View getContentHeaderView() {
        return mDecorView.getContentHeaderView();
    }

    public TitleBarEx getTitleBar() {
        return mDecorView.getTitleBar();
    }

    /***********************************
     * 有关DecorView的ViewTreeObserver的操作
     */

    /**
     * ViewTreeObserver是否Alive
     *
     * @return
     */
    protected boolean isViewTreeObserverAlive() {
        return mDecorView.getViewTreeObserver().isAlive();
    }

    protected ViewTreeObserver getViewTreeObserver() {
        return mDecorView.getViewTreeObserver();
    }

    protected boolean addOnPreDrawListener(OnPreDrawListener listener) {
        if (isViewTreeObserverAlive()) {
            getViewTreeObserver().addOnPreDrawListener(listener);
            return true;
        }
        return false;
    }

    protected void removeOnPreDrawListener(OnPreDrawListener listener) {
        getViewTreeObserver().removeOnPreDrawListener(listener);
    }

}
